using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Http;
using Publicuse.Application;
using Publicuse.Autofac;
using Publicuse.Cache;
using Publicuse.Entity;
using Publicuse.Entity;
using Publicuse.Entity.AttributeUtil;
using Publicuse.Export;
using Publicuse.Interface;
using Publicuse.Util;

namespace Publicuse.Appication
{
    public class RoleApplication
    {
        private static BaesApplication baseApplication;
        private static RoleApplication userApplication;

        public static RoleApplication GetApplication(ServiceContainer container)
        {
            baseApplication = new BaesApplication(container);
            return userApplication;
        }

        static RoleApplication()
        {
            userApplication = new RoleApplication();
        }

    /// <summary>
    /// 获取角色详细信息
    /// </summary>
    /// <param name="Id"></param>
    /// <returns></returns>
    public async Task<CommonResult> GetDetail(int Id)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                var list = baseApplication.mySqlSugar.QueryByExpression<Role>(
                    o => o.Id == Id,
                    out var msg
                );
                if (string.IsNullOrEmpty(msg) && list != null && list.Count > 0)
                {
                    var role = list.FirstOrDefault();
                    result.data = role;
                }
                result.msg = msg;
                return result;
            });
        }

        /// <summary>
        /// 获取所有角色信息
        /// </summary>
        /// <returns></returns>
        public async Task<CommonResult> GetRoleAll(Role query)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                string msg = string.Empty;
                baseApplication.baseServiceExt.ExcuteCustom(
                    db =>
                    {
                        var exp = query.GetQueryExpression<Role>(null, out msg);
                        int tottal = 0;
                        var rolelist = db.Queryable<Role>()
                            .LeftJoin<Role>((a, b) => a.parentId == b.Id)
                            .Where(exp)
                            .Select(
                                (a, b) =>
                                    new
                                    {
                                        Id = a.Id,
                                        rName = a.rName,
                                        parentName = b.rName,
                                        status = a.status,
                                        Remark = a.Remark,
                                        cTime = a.cTime,
                                        uTime = a.uTime,
                                        parentId = a.parentId,
                                        ischecked = false
                                    }
                            )
                            .OrderByDescending(a => a.Id)
                            .ToPageList(1, 1000, ref tottal)
                            .ToList();
                        if (rolelist != null && rolelist.Count > 0)
                        {
                            result.data = rolelist;
                            result.count = tottal;
                        }
                    },
                    out msg
                );
                result.msg = msg;
                return result;
            });
        }

        /// <summary>
        /// 获取角色信息列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetList(Role query)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                var tableName = TableAtributeUtil.GetTable<Role>();
                tableName =
                    $"(select a.*,b.rName as pName from {tableName} a left join {tableName} b on b.Id=a.parentid) as urp";
                string sql = query.GetQueryString<Role>(null);
                var LoginCode = HttpContextExtendBase.GetLoginCode();
                if (string.Compare(LoginCode, "ajng", true) != 0)
                {
                    var LoginRsId = HttpContextExtendBase.GetLoginrId();
                    if (!string.IsNullOrEmpty(LoginRsId))
                    {
                        sql += $" and Id in({LoginRsId}) ";
                    }
                }
                RoleQuery roleQuery = new RoleQuery()
                {
                    tableName = tableName,
                    sqlWhere = sql,
                    sortFile = query.sortFile,
                    sortType = query.sortType,
                    files = query.files,
                    pageIndex = query.pageIndex,
                    pageSize = query.pageSize,
                };
                return baseApplication.GetList<Role>(roleQuery, false).GetAwaiter().GetResult();
            });
        }

        /// <summary>
        /// 根据角色名称获取所有信息
        /// </summary>
        /// <param name="rName"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetListc(string rName)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                var table = TableAtributeUtil.GetTable<Role>();
                var sql = $"select Id,rName,parentId,rCode from {table} where status<>-9 ";
                if (!string.IsNullOrEmpty(rName))
                {
                    sql += $" and rName like @rName ";
                }
                sql += " order by Id desc; ";
                var list = baseApplication.mySqlSugar.QueryBySqlPara<Role>(
                    sql,
                    new { rName = $"%{rName}%" },
                    out var msg
                );
                result.msg = msg;
                result.data = list;
                return result;
            });
        }

        /// <summary>
        /// 获取所有角色信息
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetListd(string type)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                var table = TableAtributeUtil.GetTable<Role>();
                var list = baseApplication.mySqlSugar.QueryByExpression<Role>(
                    o => o.status !=-9,
                    out var msg
                );
                if (string.IsNullOrEmpty(msg) && list != null && list.Count > 0)
                {
                    if (!string.IsNullOrEmpty(type))
                    {
                        List<string> rlist = new List<string>() { "审核", "批量审核", "核码" };
                        list = list.Where(o => rlist.Any(b => b == o.rName)).ToList();
                    }
                    result.data = list;
                }
                result.msg = msg;
                return result;
            });
        }

        /// <summary>
        /// 绑定用户角色信息
        /// </summary>
        /// <param name="saveUserRoles"></param>
        /// <returns></returns>
        public async Task<CommonResult> SaveUserRole(SaveUserRole saveUserRoles)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                var user = TableAtributeUtil.GetTable<User>();
                var userrole = TableAtributeUtil.GetTable<UserRole>();
                StringBuilder stringBuilder = new StringBuilder();
                foreach (var uId in saveUserRoles.uids.Split(','))
                {
                    if (string.IsNullOrEmpty(uId.Trim()))
                    {
                        continue;
                    }
                    var sql = $"select * from {user} a where a.uCode=@uCode and a.status<>-9 ; ";
                    var userdata = baseApplication.mySqlSugar.QueryBySqlPara<User>(
                        sql,
                        new { uCode = uId },
                        out var msg
                    );
                    if (string.IsNullOrEmpty(msg) && userdata != null && userdata.Count > 0)
                    {
                        var uIdb = userdata.FirstOrDefault().Id;
                        foreach (var rid in saveUserRoles.rids.Split(','))
                        {
                            sql =
                                $"select * from {user} a left join {userrole} b on a.Id=b.uId where a.uCode='{uId}'  and b.rids='{rid}' and a.status<>-9 and b.status<>-9; ";
                            var list = baseApplication.mySqlSugar.Query<UserRole>(sql, out msg);
                            if (string.IsNullOrEmpty(msg) && list != null && list.Count == 0)
                            {
                                UserRole userRole = new UserRole()
                                {
                                    uId = uIdb,
                                    rids = rid,
                                    status = 1,
                                    cTime = DateTime.Now
                                };
                                baseApplication.mySqlSugar.Insert<UserRole>(userRole, out msg);
                                if (!string.IsNullOrEmpty(msg))
                                {
                                    stringBuilder.Append(msg + "|" + sql);
                                }
                            }
                        }
                    }
                }
                result.msg = stringBuilder.ToString();
                UserAuthorCache.AddUserRolecache(baseApplication.mySqlSugar, true, true);
                return result;
            });
        }

        /// <summary>
        /// 获取角色信息树形列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetTreeList(RoleQuery query)
        {
            var tableName = TableAtributeUtil.GetTable<Role>();
            string sql = query.GetQueryString<RoleQuery>(null);
            RoleQuery roleQuery = new RoleQuery()
            {
                tableName = tableName,
                sqlWhere = sql,
                sortFile = "Id",
                sortType = "desc",
                files = "*",
                pageIndex = query.pageIndex,
                pageSize = query.pageSize,
            };
            var result = await baseApplication.GetList<Role>(roleQuery, false);
            List<RoleTree> list = new List<RoleTree>();
            if (result.success)
            {
                var data = result.data as List<Role>;
                var pdata = data.Where(o => o.parentId == 0).FirstOrDefault();
                var roleTree = pdata.AutoFormModel<RoleTree, Role>(
                    (par) =>
                    {
                        par.ForMember(d => d.children, opt => opt.Ignore());
                    }
                );
                roleTree.children = data.Where(o => o.parentId > 0).ToList();
                list.Add(roleTree);
                result.data = list;
            }
            return result;
        }

        /// <summary>
        /// 检查角色名称是否存在
        /// </summary>
        /// <param name="rName"></param>
        /// <param name="sId"></param>
        /// <param name="loginUserCode"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<CommonResult> CheckRoleName(
            string rName,
            string loginUserCode,
            string Id = ""
        )
        {
            return await baseApplication.CheckDataExists<Role>(
                BusinessType.role,
                BusinessLogType.writeLogToDataBase,
                o => o.rName == rName && o.status != -9,
                "检查角色名称是否存在",
                Id
            );
        }

    /// <summary>
    /// 检查角色编码是否存在
    /// </summary>
    /// <param name="rCode"></param>
    /// <param name="loginUserCode"></param>
    /// <param name="Id"></param>
    /// <returns></returns>
    public async Task<CommonResult> CheckRoleCode(
        string rCode,
        string loginUserCode,
        string Id = ""
    )
    {
      return await baseApplication.CheckDataExists<Role>(
          BusinessType.role,
          BusinessLogType.writeLogToDataBase,
          o => o.rCode == rCode && o.status != -9,
          "检查角色编码是否存在",
          Id
      );
    }

    /// <summary>
    /// 新增修改角色信息
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    public async Task<CommonResult> AddOrUpdate(Role info)
        {
            return await baseApplication.AddOrUpdate<Role>(
                info,
                BusinessType.role,
                BusinessLogType.writeLogToDataBase,
                null,
                (data) =>
                {
                    UserAuthorCache.AddRolecache(baseApplication.mySqlSugar, true, true);
                },
                rid =>
                {
                    SysCommonCache.InitRole(baseApplication.mySqlSugar);
                }
            );
        }

        /// <summary>
        /// 删除角色信息
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="loginUserCode"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public async Task<CommonResult> Delete(string Id, string loginUserCode, string type)
        {
            return await baseApplication.Delete<Role>(
                Id,
                loginUserCode,
                type,
                BusinessType.role,
                (a, b, newId) =>
                {
                    CommonResult result = new CommonResult();
                    string msg = string.Empty;
                    loginUserCode = HttpContextExtendBase.GetLoginCode();
                    //if (string.Compare(loginUserCode, "ajng", true) != 0)
                    //{
                    //    result.code = (int)CodeResult.nolegitimate;
                    //    result.msg = ImplementResult.Nopermissiontooperate.GetRemark();
                    //    result.data = null;
                    //    result.count = 0;
                    //    return result;
                    //}
                    Role info = new Role();
                    baseApplication.mySqlSugar.QueryInfoByID(
                        newId.GetIntValue(),
                        out msg,
                        out info
                    );
                    if (info == null)
                    {
                        result.code = (int)CodeResult.fail;
                        result.msg = ImplementResult.WorkErr.GetRemark();
                        result.data = null;
                        result.count = 0;
                        return result;
                    }
                    if (info.Id > 0)
                    {
                        if (string.Compare(info.rName, "超级管理员", true) == 0)
                        {
                            result.code = (int)CodeResult.fail;
                            result.msg = "系统数据不能删除!";
                            result.data = null;
                            result.count = 0;
                            return result;
                        }
                        var tableName = TableAtributeUtil.GetTable<Role>();
                        string sql = string.Empty;
                        if (type == "-9")
                        {
                            sql = $"update {tableName} set status=-9 where Id='{info.Id}';";
                            baseApplication.mySqlSugar.ExecuteSql(sql, null, out msg);
                            result.msg = msg;
                        }
                        else
                        {
                            tableName = TableAtributeUtil.GetTable<UserRole>();
                            sql = string.Format(
                                "select Id from {0} where FIND_IN_SET(@rids,rids)",
                                tableName
                            );
                            var dt = baseApplication.mySqlSugar.GetDataTable(
                                sql,
                                new { rids = $"'{Id}'" },
                                out msg
                            );
                            if (dt.Rows.Count > 0)
                            {
                                if (string.Compare(loginUserCode, "admin", true) == 0)
                                {
                                    var urId = dt.Rows[0]["Id"].ToString().GetIntValue();
                                    sql = $"delete from '{tableName}' where Id=@Id;";
                                    baseApplication.mySqlSugar.ExecuteSql(
                                        sql,
                                        new { Id = urId },
                                        out msg
                                    );
                                }
                                else
                                {
                                    result.code = (int)CodeResult.fail;
                                    result.msg = "当前角色已经绑定用户信息，请先解除已它关联的用户信息!";
                                    result.data = null;
                                    result.count = 0;
                                    return result;
                                }
                            }

                            tableName = TableAtributeUtil.GetTable<URPermission>();
                            sql = string.Format("select Id from {0} where rId=@rId", tableName);
                            dt = baseApplication.mySqlSugar.GetDataTable(
                                sql,
                                new { rId = $"'{Id}'" },
                                out msg
                            );
                            if (dt.Rows.Count > 0)
                            {
                                if (string.Compare(loginUserCode, "admin", true) == 0)
                                {
                                    var uruId = dt.Rows[0]["Id"].ToString().GetIntValue();
                                    sql = $"delete from '{tableName}' where Id='{uruId}';";
                                    baseApplication.mySqlSugar.ExecuteSql(sql, null, out msg);
                                }
                                else
                                {
                                    result.code = (int)CodeResult.fail;
                                    result.msg = "当前角色已经绑定用户资源信息，请先解除已它关联的用户资源信息!";
                                    result.data = null;
                                    result.count = 0;
                                    return result;
                                }
                            }
                            tableName = TableAtributeUtil.GetTable<Role>();
                            sql = $"delete from {tableName} where Id='{info.Id}';";
                            baseApplication.mySqlSugar.ExecuteSql(sql, null, out msg);
                            result.msg = msg;
                        }
                    }
                    else
                    {
                        result.msg = "[" + Id + "]角色信息不存在";
                    }
                    UserAuthorCache.AddRolecache(baseApplication.mySqlSugar, true, true);
                    return result;
                }
            );
        }

        /// <summary>
        /// 还原角色信息
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="loginUserCode"></param>
        /// <returns></returns>
        public async Task<CommonResult> Reduction(string Id, string loginUserCode)
        {
            return await baseApplication.Reduction<Role>(
                Id,
                loginUserCode,
                BusinessType.role,
                (a, b, info) =>
                {
                    return info.rName;
                },
                (db, data) =>
                {
                    UserAuthorCache.AddRolecache(baseApplication.mySqlSugar, true, true);
                }
            );
        }

        /// <summary>
        /// 获取用户绑定角色信息
        /// </summary>
        /// <param name="uId"></param>
        /// <param name="loginUserCode"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetUserRoleList(string uId, string loginUserCode)
        {
            return await baseApplication.DoAction(
                BusinessType.user,
                BusinessActionType.update,
                BusinessLogType.NoWrite,
                loginUserCode,
                uId,
                "获取用户绑定角色信息",
                (mySqlSugar) =>
                {
                    string msg = string.Empty;
                    CommonResult result = new CommonResult();
                    var tableName = TableAtributeUtil.GetTable<Role>();

                    RoleQuery queryb = new RoleQuery()
                    {
                        tableName = tableName,
                        sqlWhere = "  where status<>-9 ",
                        sortFile = "Id",
                        sortType = "asc",
                        pageIndex = 1,
                        pageSize = 100000,
                        files = "*"
                    };
                    List<Role> list = new List<Role>();
                    List<RoleExtend> roleExtend = new List<RoleExtend>();
                    long totalCount = 0;
                    var LoginCode = HttpContextExtendBase.GetLoginCode();
                    if (string.Compare(LoginCode, "ajng", true) != 0)
                    {
                        var LoginRsId = HttpContextExtendBase.GetLoginRsId();
                        var LoginrId = HttpContextExtendBase.GetLoginrId();
                        queryb.sqlWhere +=
                            $" and (FIND_IN_SET('{LoginRsId}',sId) and Id='{LoginrId}') or  Id=1  ";
                    }
                    baseApplication.mySqlSugar.GetList(queryb, out msg, out list, out totalCount);
                    if (list.Count > 0)
                    {
                        roleExtend = list.MapToList<RoleExtend, Role>(o => { }) as List<RoleExtend>;
                    }
                    tableName = TableAtributeUtil.GetTable<UserRole>();
                    string sql = $"select rids from {tableName} where uId=@uId;";
                    var data = baseApplication.mySqlSugar.GetDataTable(
                        sql,
                        new { uId = uId },
                        out msg
                    );
                    foreach (DataRow item in data.Rows)
                    {
                        var rIds = item["rids"].ToString().Split(',');
                        foreach (var role in roleExtend)
                        {
                            if (rIds.Any(o => o == role.Id.ToString()))
                            {
                                role.ischecked = true;
                            }
                        }
                    }
                    result.data = roleExtend;
                    return result;
                }
            );
        }

        /// <summary>
        /// 绑定用户角色信息
        /// </summary>
        /// <param name="Role"></param>
        /// <returns></returns>
        public async Task<CommonResult> AddRoleToUser(string uId, string rId, string loginUserCode)
        {
            return await baseApplication.DoAction(
                BusinessType.user,
                BusinessActionType.update,
                BusinessLogType.writeLogToDataBase,
                loginUserCode,
                "用户编号：" + uId + "|角色编号：" + rId,
                "绑定用户角色信息",
                (baseService) =>
                {
                    CommonResult result = new CommonResult();
                    var table = TableAtributeUtil.GetTable<UserRole>();
                    var tableb = TableAtributeUtil.GetTable<URPermission>();
                    string msg = string.Empty;
                    string sql = string.Empty;
                    var LoginCode = HttpContextExtendBase.GetLoginCode();
                    var LoginAppid = HttpContextExtendBase.GetLoginAppid();
                    if (
                        string.Compare(LoginCode, "ajng", true) != 0
                        && string.Compare(LoginAppid, "admin", true) != 0
                    )
                    {
                        result.msg = ImplementResult.Nopermissiontooperate.GetRemark();
                        return result;
                    }
                    if (string.IsNullOrEmpty(rId) && string.IsNullOrEmpty(uId))
                    {
                        result.msg = ImplementResult.ParameterException.GetRemark();
                        return result;
                    }
                    if (!string.IsNullOrEmpty(uId) && string.IsNullOrEmpty(rId))
                    {
                        sql =
                            $"delete from {table}  where uId={uId};delete from {tableb} where uId={uId};";
                        baseService.ExecuteSql(sql, null, out msg);
                        result.msg = msg;
                        UserAuthorCache.AddUserRolecache(baseService, true, true);
                        UserAuthorCache.AddURMcache(baseService, true, true);
                        return result;
                    }
                    sql = $"select * from {table} where uId='{uId}';";
                    var list = baseService.Query<UserRole>(sql, out msg);
                    if (string.IsNullOrEmpty(msg))
                    {
                        if (list.Count > 0)
                        {
                            var paramJSON = uId + "-" + rId + "-" + loginUserCode;
                            var tableName = TableAtributeUtil.GetTable<UserRole>();
                            sql = $"update {tableName} set rids='{rId}' where uId='{uId}';";
                            baseService.ExecuteSql(sql, null, out msg);
                            result.msg = msg;
                        }
                        else
                        {
                            UserRole userRole = new UserRole()
                            {
                                uId = uId.GetIntValue(),
                                rids = rId,
                                status = 1
                            };
                            baseService.Insert(userRole, out msg);
                            result.msg = msg;
                        }
                        UserAuthorCache.AddUserRolecache(baseService, true, true);
                        UserAuthorCache.AddURMcache(baseService, true, true);
                    }
                    else
                    {
                        result.msg = "nouser:当前账号不存在";
                    }
                    return result;
                }
            );
        }

        /// <summary>
        /// 绑定多个用户角色信息
        /// </summary>
        /// <param name="Role"></param>
        /// <returns></returns>
        public async Task<CommonResult> AddRoleToUsers(string uId, string rId, string loginUserCode)
        {
            return await baseApplication.DoAction(
                BusinessType.user,
                BusinessActionType.update,
                BusinessLogType.writeLogToDataBase,
                loginUserCode,
                uId + "|" + rId,
                "绑定多个用户多个角色信息",
                (baseService) =>
                {
                    CommonResult result = new CommonResult();
                    string msg = string.Empty;
                    var LoginCode = HttpContextExtendBase.GetLoginCode();
                    var LoginAppid = HttpContextExtendBase.GetLoginAppid();
                    if (
                        string.Compare(LoginCode, "ajng", true) != 0
                        && string.Compare(LoginAppid, "admin", true) != 0
                    )
                    {
                        result.msg = ImplementResult.Nopermissiontooperate.GetRemark();
                        return result;
                    }
                    if (string.IsNullOrEmpty(rId) || string.IsNullOrEmpty(uId))
                    {
                        result.msg = ImplementResult.ParameterException.GetRemark();
                        return result;
                    }
                    var paramJSON = uId + "-" + rId + "-" + loginUserCode;
                    var tableName = TableAtributeUtil.GetTable<UserRole>();
                    string sql = $"delete from {tableName} where uId in({uId});";
                    baseService.ExecuteSql(sql, null, out msg);
                    if (string.IsNullOrEmpty(msg))
                    {
                        var uids = uId.Split(',');
                        foreach (var item in uids)
                        {
                            UserRole userRole = new UserRole()
                            {
                                uId = item.GetIntValue(),
                                rids = rId,
                                status = 1
                            };
                            baseService.Insert(userRole, out msg);
                        }
                        UserAuthorCache.AddUserRolecache(baseService, true, true);
                    }
                    result.msg = msg;
                    return result;
                }
            );
        }
    }
}
